/* 监控多个文件描述符的一种方法时分别为每个描述符使用一个独立的进程
 * 其中可以用父进程监控第一个文件描述符，子进程监控第二个文件描述符
 * 每个进程都会将其文件内容送到标准输出中，如果监控的是两个命名管道，那么当输入可用时就会出现输出*
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include "restart.h"

// 使用select函数创建阻塞进程
int whichisready(int fd1, int fd2){
	int maxfd, nfds;
	fd_set readset;

	// 判断select函数是否可以正常工作
	if( (fd1 < 0) || (fd2 < 0) || (fd1 >= FD_SETSIZE) || (fd2 >= FD_SETSIZE)){
		errno = EINVAL;
		return -1;
	}

	// 获取最大的文件描述符
	maxfd = fd1 > fd2 ? fd1 : fd2;
	
	FD_ZERO(&readset);

	FD_SET(fd1, &readset);
	FD_SET(fd2, &readset);

	// 使用select函数进行监听
	nfds = select(maxfd+1, &readset, NULL, NULL, NULL);
	if(nfds == -1){
		return -1;
	}

	// 判断那个文件描述符符合条件
	if(FD_ISSET(fd1, &readset)){
		return fd1;
	}
	if(FD_ISSET(fd2, &readset)){
		return fd2;
	}

	errno = EINVAL;
	return -1;

}

int main(int argc, char *argv[]){
	pid_t child_pid;
	int fd, fd1, fd2;
	int bytesread;

	if(argc != 3){
		fprintf(stderr, "Usage: %s file1 file2\n", argv[0]);
		return -1;
	}

	// 此时打开两个文件,此时需要引入头文件fcntl.h
	fd1 = open(argv[1], O_RDONLY);
	if(fd1 == -1){
		fprintf(stderr, "Failed too open file %s:%s\n", argv[1], strerror(errno));
		return 1;
	}
	
	fd2 = open(argv[2], O_RDONLY);
	if(fd2 == -1){
		fprintf(stderr, "Failed too open file %s:%s\n", argv[2], strerror(errno));
		return 1;
	}


	// 此时创建子进程，分别在两个进程中处理文件
	child_pid = fork();
	if(child_pid == -1){
		perror("Failed to create child process");
		return 1;
	}

	// 子进程处理
	if(child_pid == 0){
		fd = fd1;
	}else{
		fd = fd2;
	}

	// 将文件中的内容打印到屏幕上
	bytesread = copyfile(fd, STDOUT_FILENO);
	fprintf(stderr, "Bytes read: %d\n", bytesread);

	// int fd_val = whichisready(fd1, fd2);
	// bytesread = copyfile(fd_val, STDOUT_FILENO);
	// fprintf(stderr, "Bytes read: %d\n", bytesread);

	return 0;
}

